package com.yt.fras.filter;

import com.alibaba.fastjson.JSON;
import com.yt.fras.constant.ResultCode;
import com.yt.fras.pojo.base.JsonResult;
import com.yt.fras.pojo.base.LoginUser;
import com.yt.fras.service.impl.UserDetailsServiceImpl;
import com.yt.fras.utils.JwtTokenUtil;
import com.yt.fras.utils.RedisUtil;
import com.yt.fras.utils.ResultTool;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * ClassName:JwtAuthTokenFilter
 * Package:com.yt.fras.filter
 * Description:
 * JWT请求认证过滤器
 *
 * @date:2021/10/3 14:16
 * @author:yt
 */

@Component
public class JwtAuthTokenFilter extends OncePerRequestFilter {
    @Autowired
    private JwtTokenUtil jwtTokenUtil;

    @Autowired
    private UserDetailsServiceImpl userDetailsService;

    @Autowired
    private RedisUtil redisUtil;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        //http  请求头中的token
        String token = request.getHeader(jwtTokenUtil.getHeader());
        if (token != null && token.length() > 0) {
            String username = jwtTokenUtil.getUsernameFromToken(token);
            if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
                LoginUser loginUser = (LoginUser) userDetailsService.loadUserByUsername(username);
                String device = request.getHeader("device");
                String version;
                if (StringUtils.isNotBlank(device) && "Android".equals(device)) {
                    version = (String) redisUtil.hGet(loginUser.getUsername(), "androidVersion");
                } else {
                    version = (String) redisUtil.hGet(loginUser.getUsername(), "version");
                }
                //先校验版本，挤下线
                boolean isSuccess = jwtTokenUtil.checkVersion(token, version);
                if (!isSuccess) {
                    JsonResult result = ResultTool.fail(ResultCode.USER_ACCOUNT_USE_BY_OTHERS);
                    //处理编码方式，防止中文乱码的情况
                    response.setContentType("text/json;charset=utf-8");
                    //塞到HttpServletResponse中返回给前台
                    response.getWriter().write(JSON.toJSONString(result));
                    return;
                }
                if (jwtTokenUtil.validateToken(token, loginUser)) {
                    //给使用该JWT令牌的用户进行授权
                    UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities());
                    //设置用户身份授权
                    SecurityContextHolder.getContext().setAuthentication(authenticationToken);
                }
            }
        }
        filterChain.doFilter(request, response);
    }
}
